<template>
	<el-collapse v-model="activeNames" class="g-field-collapse" :class="{ '--disable': toggle && !modelValue }">
		<el-collapse-item
			:disabled="!modelValue"
			class="g-field-collapse-panel"
			name="collapseItem"
			:class="{
				'--has-toolbox': visibleToolbox
			}"
		>
			<template #title>
				<i class="g-field-show-placeholder">
					<el-switch v-if="toggle" :model-value="modelValue" class="--small" size="small" @click.stop @change="toggleVisible" />
				</i>
				<template v-if="tooltip">
					<el-tooltip effect="blue" placement="top" :offset="2">
						<template #content>
							<slot name="tooltip">{{ tooltip }}</slot>
						</template>
						<label class="g-field-title-with-description" :title="label">
							{{ label }}
						</label>
					</el-tooltip>
				</template>
				<label v-else class="g-field-title" :title="label">
					{{ label }}
				</label>
				<div v-if="visibleToolbox" class="g-field-collapse-panel-toolbox">
					<i v-if="showToolboxRow" class="v-icon-layout-row toolbox-icon" :class="{ '--selected': isLayoutRow }" @click.stop="isLayoutRow = true" />
					<i
						v-if="showToolboxCol"
						class="v-icon-layout-column toolbox-icon"
						:class="{ '--selected': !isLayoutRow }"
						@click.stop="isLayoutRow = false"
					/>
					<span v-if="showToolboxSplit" class="g-field-collapse-panel-toolbox-split" />

					<template v-if="showToolboxCopy">
						<el-tooltip effect="blue" placement="top" :offset="2" :disabled="!copyState.disabled" :content="copyState.msg">
							<i class="v-icon-copy toolbox-icon" :class="{ '--disabled': copyState.disabled }" @click.stop="copyData" />
						</el-tooltip>
					</template>
					<template v-if="showToolboxAdd">
						<el-tooltip effect="blue" placement="top" :offset="2" :disabled="!addState.disabled" :content="addState.msg">
							<i class="v-icon-plus toolbox-icon" :class="{ '--disabled': addState.disabled }" @click.stop="addData" />
						</el-tooltip>
					</template>
					<template v-if="showToolboxDel">
						<el-tooltip effect="blue" placement="top" :offset="2" :disabled="!deleteState.disabled" :content="deleteState.msg">
							<i class="v-icon-delete toolbox-icon" :class="{ '--disabled': deleteState.disabled }" @click.stop="deleteData" />
						</el-tooltip>
					</template>
				</div>
			</template>

			<template v-if="mode === 'layout'">
				<template v-if="list && list.length > 0">
					<el-tabs v-if="isLayoutRow" v-model="activeTab" type="border-card" class="g-field-tabs">
						<el-tab-pane v-for="(item, idx) in list" :key="idx" :label="getTabLabel(idx)">
							<slot :item="item" />
						</el-tab-pane>
					</el-tabs>
					<div v-else class="g-field-tabs --column">
						<div v-for="(item, idx) in list" :key="idx" class="g-field-tabs-column-item">
							<span class="g-field-tabs-column-item-head" :class="{ '--selected': idx === +activeTab }" @click="changeTab(idx)">
								{{ getTabLabel(idx) }}
							</span>
							<slot :item="item" />
						</div>
					</div>
				</template>
				<span v-else class="g-field-collapse-panel-empty"> 列表为空 </span>
			</template>
			<slot v-else />
		</el-collapse-item>
	</el-collapse>
</template>

<script lang="ts">
import { defineComponent, ref, watch, PropType, computed } from "vue";
import { cloneDeep } from "lodash-es";
import { UPDATE_MODEL_EVENT } from "../../../../utils/constants";
import { ToolboxType } from "@/datav/types/enums";

export default defineComponent({
	name: "GFieldCollapse",
	props: {
		mode: {
			type: String as PropType<"" | "layout">,
			default: ""
		},
		label: {
			type: String,
			required: true
		},
		tooltip: {
			type: String
		},
		toggle: {
			type: Boolean,
			default: false
		},
		modelValue: {
			type: Boolean,
			default: true
		},
		// 默认展开
		expand: {
			type: Boolean,
			default: false
		},
		defaultLayout: {
			type: String as PropType<ToolboxType.horizontal | ToolboxType.vertical>,
			default: ToolboxType.horizontal
		},
		features: {
			type: Array as PropType<ToolboxType[]>,
			default: () => [] as PropType<ToolboxType[]>
		},
		list: Array,
		min: {
			type: Number,
			default: 0
		},
		max: {
			type: Number,
			default: 1000
		},
		tab: String,
		addItem: {
			type: Function,
			default: () => {}
		}
	},
	emits: [UPDATE_MODEL_EVENT],
	setup(props, ctx) {
		const activeNames = ref([]);
		if (props.expand) {
			activeNames.value.push("collapseItem");
		}
		const activeTab = ref("0");
		const isLayoutRow = ref(props.defaultLayout === ToolboxType.horizontal);

		const visibleToolbox = computed(() => {
			return activeNames.value.length > 0 && props.features.length > 0;
		});

		const showToolboxRow = computed(() => {
			return props.features.includes(ToolboxType.horizontal);
		});

		const showToolboxCol = computed(() => {
			return props.features.includes(ToolboxType.vertical);
		});

		const showToolboxCopy = computed(() => {
			return props.features.includes(ToolboxType.copy);
		});

		const showToolboxAdd = computed(() => {
			return props.features.includes(ToolboxType.add);
		});

		const showToolboxDel = computed(() => {
			return props.features.includes(ToolboxType.remove);
		});

		const showToolboxSplit = computed(() => {
			return (showToolboxRow.value || showToolboxCol.value) && (showToolboxCopy.value || showToolboxAdd.value || showToolboxDel.value);
		});

		const copyState = computed(() => {
			const disabled = !props.list || props.list.length < props.min || props.list.length >= props.max;
			const msg = disabled ? "不可复制" : "";
			return {
				disabled,
				msg
			};
		});

		const addState = computed(() => {
			const disabled = !props.list || props.list.length >= props.max;
			const msg = disabled ? "已至最大项数" : "";
			return {
				disabled,
				msg
			};
		});

		const deleteState = computed(() => {
			const disabled = !props.list || props.list.length <= props.min;
			const msg = disabled ? "已至最小项数" : "";
			return {
				disabled,
				msg
			};
		});

		const toggleVisible = (nv: boolean) => {
			ctx.emit(UPDATE_MODEL_EVENT, nv);
		};

		const copyData = () => {
			if (!copyState.value.disabled) {
				const idx = Math.min(+activeTab.value, props.list.length - 1);
				// eslint-disable-next-line vue/no-mutating-props
				props.list.push(cloneDeep(props.list[idx]));
			}
		};

		const deleteData = () => {
			if (!deleteState.value.disabled) {
				const idx = Math.min(+activeTab.value, props.list.length - 1);
				// eslint-disable-next-line vue/no-mutating-props
				props.list.splice(idx, 1);
				activeTab.value = "0";
			}
		};

		const addData = () => {
			if (!addState.value.disabled && typeof props.addItem === "function") {
				const item = props.addItem() || {};
				props.list.push(item);
			}
		};

		const getTabLabel = (idx: number) => {
			return (props.tab || props.label) + (idx + 1);
		};

		const changeTab = (idx: number) => {
			activeTab.value = `${idx}`;
		};

		watch(
			() => props.modelValue,
			(nv: boolean) => {
				if (!nv) {
					activeNames.value = [];
				}
			}
		);

		return {
			activeNames,
			activeTab,
			isLayoutRow,
			visibleToolbox,
			showToolboxRow,
			showToolboxCol,
			showToolboxCopy,
			showToolboxAdd,
			showToolboxDel,
			showToolboxSplit,
			copyState,
			addState,
			deleteState,
			toggleVisible,
			copyData,
			addData,
			deleteData,
			getTabLabel,
			changeTab
		};
	}
});
</script>
<style lang="scss" scoped>
@import "field-collapse";
@import "field-tabs";
</style>
